using System;
using System.Collections.Generic;
using System.Linq;

namespace Sherwood.Content
{
    public interface IRecordRepository<TRecord> where TRecord : IRecord
    {
        /// <summary>
        /// Get record based on global unique id.
        /// </summary>
        /// <param name="id">The unique id of the record to receive</param>
        /// <returns>Returns the record instance with the given id if it exists and null if records does not exist</returns>
        TRecord this[Guid id] { get; }
        
        /// <summary>
        /// Enumerate through all records in system
        /// </summary>
        IQueryable<TRecord> All { get; }

        /// <summary>
        /// Get all records belonging to a specific client
        /// </summary>
        /// <param name="clientId">The id of the client</param>
        /// <returns>All records belonging to the client</returns>
        IQueryable<TRecord> GetByClientId(string clientId);
        
        /// <summary>
        /// Get record based on client and the foreign id (normally id in client system)
        /// </summary>
        /// <param name="clientId">The id of the client</param>
        /// <param name="referenceId">The foreign id (id in client system)</param>
        /// <returns>Returns the matching record or null if not found</returns>
        TRecord GetByReferenceId(string clientId, string referenceId);

        /// <summary>
        /// Get record based on global unique id.
        /// </summary>
        /// <param name="id">The unique id of the record to receive</param>
        /// <returns>Returns the record instance with the given id if it exists and null if records does not exist</returns>
        TRecord GetById(Guid id);

        ///<summary>
        /// Creates a new record
        ///</summary>
        ///<param name="client">The client owning this record</param>
        ///<param name="referenceId">The clients id of this record</param>
        ///<param name="title">The title of the record</param>
        ///<returns>The newly created record</returns>
        /// <exception cref="InvalidOperationException">A record with this client and referenceId already exists.</exception>
        TRecord Create(IClient client, string referenceId, string title);

        ///<summary>
        /// Iterate through records with given ids
        ///</summary>
        ///<param name="recordIds">The ids of the records to be returned</param>
        ///<returns>An enumerable data source</returns>
        IQueryable<TRecord> GetByIds(IEnumerable<Guid> recordIds);

        /// <summary>
        /// Delete the record specified
        /// </summary>
        /// <param name="record">The record to delete</param>
        void Delete(TRecord record);
    }
}